package com.qhstudio.feelingnode.tools;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

/**
 * @author wo2app
 * @date 创建时间：2015年8月30日 上午11:38:54
 * @version 1.0
 * @parameter
 * @since
 * @return
 */

public class AsyncClient extends AsyncTask<Void, Integer, Void> {

	@SuppressWarnings("unused")
	private Context context;

	public enum TYPE {
		GET, POST, UPLOAD
	};

	private String URL;
	private String[] key;
	private String[] value;
	private String file;
	private TYPE type;
	private String data = "";
	private ClientListenter listener;
	private ProgressListener progressListener;

	public AsyncClient(Context context) {
		this.context = context;
	}

	public AsyncClient(Context context, String url, TYPE type, String[] key, String[] value) {
		this.context = context;
		this.URL = url;
		this.key = key;
		this.value = value;
		this.type = type;
	}

	public AsyncClient(Context context, String url, TYPE type, Map<String, String> map) {
		String[] key = new String[map.size()];
		String[] value = new String[map.size()];
		int sp = 0;
		for (Map.Entry<String, String> entry : map.entrySet()) {
			key[sp] = entry.getKey();
			value[sp] = entry.getValue();
			sp += 1;
		}

		this.context = context;
		this.URL = url;
		this.key = key;
		this.value = value;
		this.type = type;
	}
	
	

	public AsyncClient(String url, TYPE type, String file) {
		this.URL = url;
		this.file = file;
		this.type = type;
	}

	public void setClient(String url, TYPE type, String[] key, String[] value) {
		this.URL = url;
		this.key = key;
		this.value = value;
		this.type = type;
	}

	public void setClient(String file, TYPE type, String url) {
		this.URL = url;
		this.file = file;
		this.type = type;
	}

	public void setUrl(String url) {
		this.URL = url;
	}

	public void setType(TYPE type) {
		this.type = type;
	}

	public void setKey(String[] key) {
		this.key = key;
	}

	public void setValue(String[] value) {
		this.value = value;
	}

	public void setListener(ClientListenter listenter) {
		this.listener = listenter;
	}

	@Override
	protected void onPreExecute() {
		// TODO Auto-generated method stub
		super.onPreExecute();
	}

	@Override
	protected Void doInBackground(Void... params) {
		// TODO Auto-generated method stub

		switch (type) {
		case POST:
			data = postType(URL, key, value);
			break;
		case GET:
			String tempUrl = "";
			if (key != null && value != null) {
				for (int i = 0; i < key.length; i++) {
					tempUrl += "/" + key[i] + "/" + value[i];
				}
			}
			tempUrl = URL + tempUrl;
			data = getType(tempUrl);
			break;
		case UPLOAD:
			data = uploadFile(file, URL);
			break;
		default:
			break;
		}
		return null;
	}

	@Override
	protected void onPostExecute(Void result) {
		// TODO Auto-generated method stub
		super.onPostExecute(result);
		if (this.listener != null) {
			this.listener.backData(data);
		}
	}

	@Override
	protected void onProgressUpdate(Integer... values) {
		// TODO Auto-generated method stub
		super.onProgressUpdate(values);
		debug(values.toString());
		if (progressListener != null)
			progressListener.progress(Integer.parseInt(values.toString()));
	}

	/**
	 * post方式
	 * 
	 * @param url
	 */
	@SuppressWarnings("deprecation")
	private String postType(String url, String[] key, String[] value) {
		String res = "";
		try {
			HttpPost httpPost = new HttpPost(url);
			if (key != null && value != null) {
				List<NameValuePair> list = new ArrayList<NameValuePair>();
				for (int i = 0; i < key.length; i++) {
					list.add(new BasicNameValuePair(key[i], value[i]));
				}
				httpPost.setEntity(new UrlEncodedFormEntity(list, HTTP.UTF_8));
			}
			HttpResponse httpResponse = new DefaultHttpClient().execute(httpPost);
			if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				String strResult = EntityUtils.toString(httpResponse.getEntity(), "utf-8");
				// Log.e("info_post", strResult);
				res = strResult;
			} else {
				debug("client-post-erro-" + httpResponse.getStatusLine().getStatusCode());
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			debug("client-post-erro-client");
		}

		return res;
	}

	/**
	 * get方式
	 * 
	 * @param url
	 */
	private String getType(String url) {
		String res = "";
		try {
			HttpGet httpRequest = new HttpGet(url);
			DefaultHttpClient httpClient = new DefaultHttpClient();
			HttpResponse httpResponse = httpClient.execute(httpRequest);
			if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				String strResult = EntityUtils.toString(httpResponse.getEntity(), "utf-8").trim();
				// Log.e("info", strResult);
				res = strResult;
			} else {
				debug("client-get-erro-" + httpResponse.getStatusLine().getStatusCode());
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			debug("client-get-erro-client");
		}
		return res;
	}

	/**
	 * 上传图片
	 * 
	 * @param srcPath
	 * @param uploadUrl
	 */
	public String uploadFile(String srcPath, String uploadUrl) {
		String end = "\r\n";
		String twoHyphens = "--";
		String boundary = "******";
		String backData = "";
		try {
			URL url = new URL(uploadUrl);
			HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();// http连接
			// 设置每次传输的流大小，可以有效防止手机因为内存不足崩溃
			// 此方法用于在预先不知道内容长度时启用没有进行内部缓冲的 HTTP 请求正文的流。
			httpURLConnection.setChunkedStreamingMode(128 * 1024);// 128K
			// 允许输入输出流
			httpURLConnection.setDoInput(true);
			httpURLConnection.setDoOutput(true);
			httpURLConnection.setUseCaches(false);
			// 使用POST方法
			httpURLConnection.setRequestMethod("POST");
			httpURLConnection.setRequestProperty("Connection", "Keep-Alive");// 保持一直连接
			httpURLConnection.setRequestProperty("Charset", "UTF-8");// 编码
			httpURLConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);// POST传递过去的编码
			// httpURLConnection.setRequestProperty("name", userName);

			DataOutputStream dos = new DataOutputStream(httpURLConnection.getOutputStream());// 输出流

			dos.writeBytes(twoHyphens + boundary + end);
			dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\"; filename=\""
					+ srcPath.substring(srcPath.lastIndexOf("/") + 1) + "\"" + end);
			dos.writeBytes(end);

			FileInputStream fis = new FileInputStream(srcPath);// 文件输入流，写入到内存中
			byte[] buffer = new byte[8192]; // 8k
			int count = 0;
			// 读取文件
			while ((count = fis.read(buffer)) != -1) {
				dos.write(buffer, 0, count);
			}
			fis.close();

			dos.writeBytes(end);
			dos.writeBytes(twoHyphens + boundary + twoHyphens + end);

			dos.flush();

			InputStream is = httpURLConnection.getInputStream();// http输入，即得到返回的结果
			InputStreamReader isr = new InputStreamReader(is, "utf-8");
			BufferedReader br = new BufferedReader(isr);
			String result = br.readLine();
			backData = result;

			dos.close();
			is.close();
		} catch (Exception e) {
			e.printStackTrace();
			// setTitle(e.getMessage());

		}
		return backData;
	}

	public interface ClientListenter {
		void backData(String data);
	}

	public interface ProgressListener {
		void progress(int p);
	}

	/**
	 * 打印信息
	 * 
	 * @param log
	 */
	private void debug(String log) {
		Log.e("info", log);
	}

}
